package com.johnzer.frame.utils;

import android.app.Activity;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.IBinder;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.MarginLayoutParams;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;

import com.johnzer.frame.app.BaseApp;


public class UIUtils {
    public static Context getContext() {
        return BaseApp.instance();
    }

    /**
     * 计算listview的高度
     *
     * @param listView 要计算高度的listview
     */
    public static void setListViewHeightBasedOnChildren(
            AdapterView<ListAdapter> listView) {
        // 获取ListView对应的Adapter
        if (listView == null) {
            return;
        }
        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height = caluteListViewHeight(listView);
        listView.setLayoutParams(params);
    }

    /**
     * 计算listview的高度
     *
     * @param listView 要计算高度的listview
     */
    public static int caluteListViewHeight(AdapterView<ListAdapter> listView) {
        if (null == listView) {
            return 0;
        }
        // 获取ListView对应的Adapter
        ListAdapter listAdapter = listView.getAdapter();
        if (listAdapter == null) {
            return 0;
        }
        int dividerHight = 0;
        int count = listAdapter.getCount();
//        if (listView instanceof HorizontalListView) {
//            count = 1;
//        } else
            if (listView instanceof ListView) {
            count = listAdapter.getCount();
            dividerHight = ((ListView) listView).getDividerHeight();
        }
        int totalHeight = 0;
        LogUtils.d("count = " + count + ",dividerHight = " + dividerHight);
        int height = 0;
        for (int i = 0; i < count; i++) {
            // listAdapter.getCount()返回数据项的数目
            View listItem = listAdapter.getView(i, null, listView);
            if (null == listItem) {
                return 0;
            }
            // 计算子项View 的宽高
            listItem.measure(0, 0);
            // 统计所有子项的总高度
            height = listItem.getMeasuredHeight();
            LogUtils.d("height = " + height + ",position = " + i);
            totalHeight += height;
        }
        // listView.getDividerHeight()获取子项间分隔符占用的高度
        // params.height最后得到整个ListView完整显示需要的高度
        totalHeight += (dividerHight * (count - 1)) + listView.getPaddingTop()
                + listView.getPaddingBottom();

        LogUtils.d("count = " + count + ",totalHeight = " + totalHeight);
        return totalHeight;
    }

    /**
     * 打开软键盘
     *
     * @param mEditText 输入框
     * @param mContext  上下文
     */
    public static void openKeybord(EditText mEditText, Context mContext) {
        InputMethodManager imm = (InputMethodManager) mContext
                .getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.showSoftInput(mEditText, InputMethodManager.RESULT_SHOWN);
        imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,
                InputMethodManager.HIDE_IMPLICIT_ONLY);
    }

    /**
     * 关闭软键盘
     *
     * @param mEditText 输入框
     * @param mContext  上下文
     */
    public static void closeKeybord(EditText mEditText, Context mContext) {
        InputMethodManager imm = (InputMethodManager) mContext
                .getSystemService(Context.INPUT_METHOD_SERVICE);

        imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
    }

    public static boolean isSoftBoardOpen(Activity context) {
        return context.getWindow().getAttributes().softInputMode == WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED;
    }

    /**
     * dip转换px
     */
    public static int dip2px(float dip) {
        final float scale = getDisplayMetrics(getContext()).density;
        return (int) (dip * scale + 0.5f);
    }

    /**
     * pxz转换dip
     */
    public static int px2dip(float px) {
        final float scale = getDisplayMetrics(getContext()).density;
        return (int) (px / scale + 0.5f);
    }

    /**
     * 获取主线程的handler
     */
    public static Handler getHandler() {
        return BaseApp.getMainThreadHandler();
    }

    /**
     * 延时在主线程执行runnable
     */
    public static boolean postDelayed(Runnable runnable, long delayMillis) {
        return getHandler().postDelayed(runnable, delayMillis);
    }

    /**
     * 在主线程执行runnable
     */
    public static boolean post(Runnable runnable) {
        return getHandler().post(runnable);
    }

    /**
     * 从主线程looper里面移除runnable
     */
    public static void removeCallbacks(Runnable runnable) {
        getHandler().removeCallbacks(runnable);
    }

    public static View inflate(int resId) {
        return LayoutInflater.from(getContext()).inflate(resId, null);
    }

    /**
     * 获取资源
     */
    public static Resources getResources() {
        return getContext().getResources();
    }

    /**
     * 获取文字
     */
    public static String getString(int resId) {
        return getResources().getString(resId);
    }

    /**
     * 获取文字数组
     */
    public static String[] getStringArray(int resId) {
        return getResources().getStringArray(resId);
    }

    /**
     * 获取dimen
     */
    public static int getDimens(int resId) {
        return getResources().getDimensionPixelSize(resId);
    }

    /**
     * 获取drawable
     */
    public static Drawable getDrawable(int resId) {
        return getResources().getDrawable(resId);
    }

    /**
     * 获取颜色
     */
    public static int getColor(int resId) {
        return getResources().getColor(resId);
    }

    /**
     * 获取颜色选择器
     */
    public static ColorStateList getColorStateList(int resId) {
        return getResources().getColorStateList(resId);
    }

    // 判断当前的线程是不是在主线程
    public static boolean isRunInMainThread() {
        // android.os.Process.myTid()表示调用线程的id
        return android.os.Process.myTid() == BaseApp.getMainThreadId();
    }

    public static void runInMainThread(Runnable runnable) {
        if (isRunInMainThread()) {
            runnable.run();
        } else {
            post(runnable);
        }
    }

    // *********** johzner add start **************//
    private static final float PX_WIDTH = 750f;
    private static final float PX_HEIGHT = 1333f;
    public static final int BY_HEIGHT = 0;
    public static final int BY_WIDTH = 1;
    public static final int BY_ORIGINAL = 2;
    public static final int MATCH_PARENT = MarginLayoutParams.MATCH_PARENT;
    public static final int WRAP_CONTENT = MarginLayoutParams.WRAP_CONTENT;
    public static final int NO_CHANGE = (int) PX_HEIGHT;
    private static DisplayMetrics sDisplayMetrics;

    /**
     * 获得系统屏幕信息
     */
    public static DisplayMetrics getDisplayMetrics(Context ctx) {
        if (sDisplayMetrics == null) {
            sDisplayMetrics = new DisplayMetrics();
            if (ctx instanceof Activity) {
                ((Activity) ctx).getWindowManager().getDefaultDisplay()
                        .getMetrics(sDisplayMetrics);
            }
        }
        return sDisplayMetrics;
    }

    /**
     * 获得系统屏幕宽
     */
    public static int getScreenWidth() {
        return getDisplayMetrics(BaseApp.instance()).widthPixels;
    }

    /**
     * 获得系统屏幕高
     */
    public static int getScreenHeight() {
        return getDisplayMetrics(BaseApp.instance()).heightPixels;
    }

    /**
     * 获得像素密度
     *
     * @return
     */
    public static float getDensity() {
        return getDisplayMetrics(BaseApp.instance()).density;
    }

    /**
     * @param ctx
     * @param textView
     * @param originSize
     * @param type
     */
    private static void setTextSize(Context ctx, TextView textView,
                                    float originSize, int type) {
        if (null == textView || null == ctx || originSize <= 0) {
            LogUtils.e("null == textView || null == ctx || originSize <= 0");
            return;
        }
        float baseRatio = getParamRatio(type);
        textView.setTextSize(UIUtils.px2dip(baseRatio * originSize));
    }

    /**
     * @param textView
     * @param originSize
     * @param type
     */
    public static void setTextSize(TextView textView, float originSize, int type) {
        setTextSize(BaseApp.instance(), textView, originSize,
                type);
    }

    /**
     * 获取到指定的比率
     *
     * @param type 根据这个type来计算当前控件是根据高度还是宽度为依据计算的,默认根据高度计算
     * @return
     */
    public static float getParamRatio(int type) {
        float baseRatio = getScreenHeight() / PX_HEIGHT;
        if (type == 0 || type == BY_HEIGHT) {
            baseRatio = getScreenHeight() / PX_HEIGHT;
        } else if (type == BY_WIDTH) {
            baseRatio = getScreenWidth() / PX_WIDTH;
        } else if (type == BY_ORIGINAL) {
            baseRatio = 1f;
        }
        return baseRatio;
    }

    /**
     * @param view
     * @param width
     * @param height
     * @param textSize
     * @param type
     */
    public static void setTextViewLayouParams(TextView view, int width,
                                              int height, float textSize, int type) {
        setTextViewLayouParams(view, width, height, textSize, NO_CHANGE,
                NO_CHANGE, NO_CHANGE, NO_CHANGE, type);
    }

    /**
     * 获得系统屏幕宽高比
     */
    public static float getScreenAspectRatio(Context act) {
        return (getScreenWidth() * 1.0f / getScreenHeight());
    }

    /**
     * @param view
     * @param width
     * @param height
     * @param textSize
     * @param leftMargin
     * @param topMargin
     * @param rightMargin
     * @param bottomMargin
     * @param type
     */
    public static void setTextViewLayouParams(TextView view, int width,
                                              int height, float textSize, int leftMargin, int topMargin,
                                              int rightMargin, int bottomMargin, int type) {
        setTextSize(view, textSize, type);
        setViewLayouParams(view, width, height, type);
        setViewMargin(view, leftMargin, topMargin, rightMargin, bottomMargin,
                type);
    }

    /**
     * @param view
     * @param textSize
     * @param leftMargin
     * @param topMargin
     * @param rightMargin
     * @param bottomMargin
     * @param type
     */
    public static void setTextViewMargin(TextView view, float textSize,
                                         int leftMargin, int topMargin, int rightMargin, int bottomMargin,
                                         int type) {
        setTextSize(view, textSize, type);
        setViewLayouParams(view, NO_CHANGE, NO_CHANGE, type);
        setViewMargin(view, leftMargin, topMargin, rightMargin, bottomMargin,
                type);
    }

    /**
     * @param view
     * @param textSize
     * @param leftPadding
     * @param topPadding
     * @param rightPadding
     * @param bottomPadding
     * @param type
     */
    public static void setTextViewPadding(TextView view, float textSize,
                                          int leftPadding, int topPadding, int rightPadding,
                                          int bottomPadding, int type) {
        setTextSize(view, textSize, type);
        setViewLayouParams(view, NO_CHANGE, NO_CHANGE, type);
        setViewPadding(view, leftPadding, topPadding, rightPadding,
                bottomPadding, type);
    }

    /**
     * 单纯只是设置宽高，不设置margin
     *
     * @param view   需要设置属性的控件
     * @param width  控件的宽度
     * @param height 控件的高度
     * @param type   根据这个type来计算当前控件是根据高度还是宽度为依据计算的,默认根据高度计算
     */
    public static void setViewLayouParams(View view, int width, int height,
                                          int type) {
        setViewLayouParams(view, width, height, NO_CHANGE, NO_CHANGE,
                NO_CHANGE, NO_CHANGE, type);
    }

    /**
     * 设置控件属性的方法
     *
     * @param view         需要设置属性的控件
     * @param width        控件的宽度
     * @param height       控件的高度
     * @param leftMargin   控件距离左边 的距离
     * @param topMargin    控件距离顶部的距离
     * @param rightMargin  控件距离右边的距离
     * @param bottomMargin 控件距离下边的距离
     * @param type         根据这个type来计算当前控件是根据高度还是宽度为依据计算的,默认根据高度计算
     */
    public static void setViewLayouParams(View view, int width, int height,
                                          int leftMargin, int topMargin, int rightMargin, int bottomMargin,
                                          int type) {
        setViewLayouParams(BaseApp.instance(), view, width,
                height, leftMargin, topMargin, rightMargin, bottomMargin, type);
    }

    /**
     * 设置控件属性的方法
     *
     * @param ctx          上下文对象
     * @param view         需要设置属性的控件
     * @param width        控件的宽度
     * @param height       控件的高度
     * @param leftMargin   控件距离左边 的距离
     * @param topMargin    控件距离顶部的距离
     * @param rightMargin  控件距离右边的距离
     * @param bottomMargin 控件距离下边的距离
     * @param type         根据这个type来计算当前控件是根据高度还是宽度为依据计算的,默认根据高度计算
     */
    private static void setViewLayouParams(Context ctx, View view, int width,
                                           int height, int leftMargin, int topMargin, int rightMargin,
                                           int bottomMargin, int type) {
        if (null == view || width == 0 || height == 0) {
            LogUtils.e("传入的控件为空, 或者宽高的数值为0");
            return;
        }
        // 根据type计算转换的比率，用于后边转换
        float baseRatio = getParamRatio(type);
        ViewGroup.LayoutParams params = view.getLayoutParams();
        if (width != NO_CHANGE) {
            if (width != MATCH_PARENT && width != WRAP_CONTENT) {
                width = (int) (baseRatio * width + 0.5);
            }
        }
        if (height != NO_CHANGE) {
            if (height != MATCH_PARENT && height != WRAP_CONTENT) {
                height = (int) (baseRatio * height + 0.5);
            }
        }
        if (null == params) {
            params = new ViewGroup.LayoutParams(width, height);
        } else {
            if (width != NO_CHANGE)
                params.width = width;
            // else
            // params.width = WRAP_CONTENT;

            if (height != NO_CHANGE)
                params.height = height;
            // else
            // params.height = WRAP_CONTENT;
        }
        view.setLayoutParams(params);
        setViewMargin(view, leftMargin, topMargin, rightMargin, bottomMargin,
                type);
    }

    /**
     * @param view
     * @param leftMargin
     * @param topMargin
     * @param rightMargin
     * @param bottomMargin
     * @param type
     */
    public static void setViewMargin(View view, int leftMargin, int topMargin,
                                     int rightMargin, int bottomMargin, int type) {
        if (null == view) {
            LogUtils.e("传入的控件为空");
            return;
        }
        if (!(view.getLayoutParams() instanceof MarginLayoutParams)) {
            return;
        }
        // 根据type计算转换的比率，用于后边转换
        float baseRatio = getParamRatio(type);

        MarginLayoutParams params = (MarginLayoutParams) view
                .getLayoutParams();
        // 因为margin的值可以为负数
        if (leftMargin != NO_CHANGE) {
            params.leftMargin = (int) (baseRatio * leftMargin + 0.5);
        }
        if (rightMargin != NO_CHANGE) {
            params.rightMargin = (int) (baseRatio * rightMargin + 0.5);
        }
        if (bottomMargin != NO_CHANGE) {
            params.bottomMargin = (int) (baseRatio * bottomMargin + 0.5);
        }
        if (topMargin != NO_CHANGE) {
            params.topMargin = (int) (baseRatio * topMargin + 0.5);
        }
        view.setLayoutParams(params);
    }

    /**
     * @param view
     * @param leftPadding
     * @param topPadding
     * @param rightPadding
     * @param bottomPadding
     * @param type
     */
    public static void setViewPadding(View view, int leftPadding,
                                      int topPadding, int rightPadding, int bottomPadding, int type) {
        if (null == view) {
            LogUtils.e("传入的控件为空");
            return;
        }
        // 根据type计算转换的比率，用于后边转换
        float baseRatio = getParamRatio(type);
        //
        int left = 0;
        int right = 0;
        int top = 0;
        int bottom = 0;
        if (leftPadding != NO_CHANGE) {
            left = (int) (baseRatio * leftPadding + 0.5);
        }
        if (rightPadding != NO_CHANGE) {
            right = (int) (baseRatio * rightPadding + 0.5);
        }
        if (bottomPadding != NO_CHANGE) {
            bottom = (int) (baseRatio * bottomPadding + 0.5);
        }
        if (topPadding != NO_CHANGE) {
            top = (int) (baseRatio * topPadding + 0.5);
        }
        view.setPadding(left, top, right, bottom);
    }
    // *********** johzner add end **************//

    /***/
    public static void dispathTouchEventUtil(MotionEvent ev, Activity activity) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            View v = activity.getCurrentFocus();
            if (isShouldHideKeyboard(v, ev)) {
                hideKeyboard(v.getWindowToken(), activity.getApplicationContext());
            }
        }
    }

    /**
     * 根据EditText所在坐标和用户点击的坐标相对比，来判断是否隐藏键盘，因为当用户点击EditText时则不能隐藏
     *
     * @param v
     * @param event
     * @return
     */
    private static boolean isShouldHideKeyboard(View v, MotionEvent event) {
        if (v != null && (v instanceof EditText)) {
            int[] l = {0, 0};
            v.getLocationInWindow(l);
            int left = l[0],
                    top = l[1],
                    bottom = top + v.getHeight(),
                    right = left + v.getWidth();
            if (event.getX() > left && event.getX() < right
                    && event.getY() > top && event.getY() < bottom) {
                // 点击EditText的事件，忽略它。
                return false;
            } else {
                return true;
            }
        }
        // 如果焦点不是EditText则忽略，这个发生在视图刚绘制完，第一个焦点不在EditText上，和用户用轨迹球选择其他的焦点
        return false;
    }

    /**
     * 获取InputMethodManager，隐藏软键盘
     *
     * @param token
     */
    private static void hideKeyboard(IBinder token, Context context) {
        if (token != null) {
            InputMethodManager im = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
            im.hideSoftInputFromWindow(token, InputMethodManager.HIDE_NOT_ALWAYS);
        }
    }
}